﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.ComponentModel;
using System.Data;

namespace Lyon.Util.Helper
{
    public static class Other
    {
        public static string Join(this IEnumerable source, string propertyName = null, string separator = ",")
        {
            if (source == null)
            {
                return null;
            }

            bool nullProperty = propertyName == null;
            StringBuilder sb = new StringBuilder();
            PropertyDescriptor pi = null;
            Type type = null;

            foreach (object value in source)
            {
                if (value == null)
                {
                    continue;
                }

                if (value is string || nullProperty)
                {
                    //value是string或propertyName是空的直接輸出。
                    sb.Append(value);
                }
                else if (value is DataRow)
                {
                    sb.Append(((DataRow)value)[propertyName]);
                }
                else
                {
                    Type temp = value.GetType();

                    if (type != temp)
                    {
                        type = temp;
                        // 用TypeDescriptor.GetProperties(object)取屬性有實作ICustomTypeDescriptor，會取值自定屬性，如DataRowViw
                        // 用TypeDescriptor.GetProperties(type)取屬性不會判斷ICustomTypeDescriptor。
                        pi = TypeDescriptor.GetProperties(value)[propertyName];

                        if (pi == null)
                        {
                            throw new InvalidOperationException(string.Format("{0} Property {1} Not Exist.", type, propertyName));
                        }
                    }

                    sb.Append(pi.GetValue(value));
                }

                sb.Append(separator);
            }
            return (separator == null || sb.Length == 0) ? sb.ToString() : sb.ToString(0, sb.Length - separator.Length);
        }
    }
}
